#pragma once
/* 
* COPYRIGHT 2012 Mafahir Fairoze
* 
* This file is part of Vector Template Library (Vtl) v1.0.
* (Project Website : http://mafahir.wordpress.com/projects/neuralplusplus)
* 
* Vector Template Library (Vtl) v1.0 is a free software. You can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
* 
* Vector Template Library (Vtl) v1.0 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License <http://www.gnu.org/licenses/> for more details.
*/

#include "Vtl/eigen.h"
#include "Vtl/Polygon.h"

namespace Vtl
{
	namespace geometry
	{
		/*!
		*  \brief Returns the shortest distance between the point and line.
		*  Also is the length of the perpendicular line connecting the point from the given line.
		*  \param[in] _Point 
		*  \param[in] _Line 
		*  \return Scalar 
		*/
		template <typename Scalar, int Dimension>
		inline Scalar pointToLineDistance(const Eigen::Matrix<Scalar,Dimension,1> &_Point, 
			const Eigen::ParametrizedLine<Scalar,Dimension> &_Line);

		/*!
		*  \brief Returns the shortest squared distance between the point and line.
		*  Also is the squared length of the perpendicular line connecting the point from the given line.
		*  \param[in] _Point 
		*  \param[in] _Line 
		*  \return Scalar 
		*/
		template <typename Scalar, int Dimension>
		inline Scalar sqPointToLineDistance(const Eigen::Matrix<Scalar,Dimension,1> &_Point, 
			const Eigen::ParametrizedLine<Scalar,Dimension> &_Line);

		/*!
		*  \brief Returns the closest point on the line(Ray).
		*  \param[in] _Line 
		*  \param[in] _Point 
		*  \return Scalar returns the parametric distance from the origin to the closest point.
		*/
		template <typename Scalar, int Dimension>
		inline Scalar closestPointOnLine(const Eigen::ParametrizedLine<Scalar,Dimension> &_Line, 
			const Eigen::Matrix<Scalar,Dimension,1> &_Point);

		/*!
		*  \brief Checks if the vectors are almost parallel to each other.
		*  \param[in] _DirA 
		*  \param[in] _DirB 
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if parallel.
		*/
		template <typename Scalar, int Dimension>
		inline bool vectorParallelTovector(const Eigen::Matrix<Scalar,Dimension,1> &_DirA, 
			const Eigen::Matrix<Scalar,Dimension,1> &_DirB,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Checks if the given line(Ray) goes through the point.
		*  \param[in] _Point 
		*  \param[in] _Line 
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if it does go through the point.
		*/
		template <typename Scalar, int Dimension>
		inline bool pointOnLine(const Eigen::Matrix<Scalar,Dimension,1> &_Point, 
			const Eigen::ParametrizedLine<Scalar,Dimension> &_Line,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Checks if the given line segment (from start to end of line only) goes through the point.
		*  \param[in] _Point 
		*  \param[in] _Line 
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if it does go through the point.
		*/
		template <typename Scalar, int Dimension>
		inline bool pointOnLineSegment(const Eigen::Matrix<Scalar,Dimension,1> &_Point, 
			const Eigen::ParametrizedLine<Scalar,Dimension> &_Line,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Checks if the given point is inside the Polygon face.
		*  \param[in] _Point 
		*  \param[in] _Polygon 
		*  \return bool returns TRUE if the point is inside.
		*/
		template <typename Scalar, int Dimension>
		inline bool pointInPolygon(const Eigen::Matrix<Scalar,Dimension,1> &_Point, 
			const Polygon<Scalar, Dimension> &_Polygon);
	};
};

#include "Vtl/impl/geometry.hpp"